﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using C4F.DevKit.Calendar.Components;

namespace C4F.DevKit.Calendar.Controls
{
    /// <summary>
    /// This control display a list of appointments from a calendar.
    /// </summary>
    [ToolboxItem(true), ToolboxBitmap(typeof(AppointmentsList))]
    public partial class AppointmentsList : UserControl
    {
        #region Private Data

        private List<Appointment> _appts = null;

        private CalendarService _calendarService;

        #endregion

        #region Constants

        private const string UID_GRID_COLUMN_NAME = "colHdrUID";

        private const string UID_FIELD = "UID";
        private const string LOCAL_START_DATETIME_FIELD = "LocalStartDateTime";
        private const string SUMMARY_FIELD = "Summary";
        private const string LOCATION_FIELD = "Location";
        private const string NOTES_FIELD = "Notes";

        #endregion

        #region Properties

        /// <summary>
        /// The appointments viewed in this control.
        /// </summary>
        [Browsable(false)]
        public List<Appointment> Appointments
        {
            get
            {
                return _appts;
            }
            set
            {
                _appts = value;
                
                if (_appts != null)
                {
                    _appts.Sort(CompareAppointments);
                }

                ConfigureBindings();
            }
        }

        /// <summary>
        /// The UID of the currently selected appointment.
        /// </summary>
        [Browsable(false)]
        public Guid SelectedAppointmentID
        {
            get
            {
                Guid returnValue = Guid.Empty;

                if (dataGridView1.SelectedRows.Count > 0 && dataGridView1.SelectedRows[0].Cells[UID_GRID_COLUMN_NAME].Value != null)
                {
                    Appointment appt = GetAppointmentFromList((Guid)dataGridView1.SelectedRows[0].Cells[UID_GRID_COLUMN_NAME].Value);

                    if (appt != null)
                    {
                        returnValue = appt.UID;
                    }
                }

                return returnValue;
            }            
        }

        /// <summary>
        /// The currently selected appointment.
        /// </summary>
        [Browsable(false)]
        public Appointment SelectedAppointment
        {
            get
            {
                if (dataGridView1.SelectedRows.Count > 0)
                {
                    return this.GetAppointmentFromList((Guid)dataGridView1.SelectedRows[0].Cells[UID_GRID_COLUMN_NAME].Value);
                }
                else
                {
                    return null;
                }
            }
        }

        /// <summary>
        /// The CalendarService to use with this control and with its
        /// appointments.
        /// </summary>
        [Browsable(true)]
        public CalendarService CalendarService
        {
            get
            {
                return _calendarService;
            }
            set
            {
                _calendarService = value;
            }
        }

        #endregion Properties

        #region Constructor

        /// <summary>
        /// Creates a new AppointmentList control.
        /// </summary>
        public AppointmentsList()
        {
            InitializeComponent();

            if (!DesignMode)
                ConfigureBindings();
        }

        #endregion Constructor

        #region Private Methods

        private void ConfigureBindings()
        {
            bindingSource1.DataSource = _appts;

            colHdrDate.DataPropertyName = LOCAL_START_DATETIME_FIELD;
            colHdrSubject.DataPropertyName = SUMMARY_FIELD;
            colHdrLocation.DataPropertyName = LOCATION_FIELD;
            colHdrNotes.DataPropertyName = NOTES_FIELD;
            colHdrUID.DataPropertyName = UID_FIELD;
        }

        private Appointment GetAppointmentFromList(Guid uid)
        {

            Appointment returnValue = null;
            foreach (Appointment appt in _appts)
            {
                if (appt.UID == uid)
                {
                    returnValue =  appt;
                    break;
                }
            }

            return returnValue;
        }

        private int CompareAppointments(Appointment leftAppt, Appointment rightAppt)
        {
            if (leftAppt == null)
            {
                if (rightAppt == null)
                {
                    return 0;
                }
                else
                {
                    return -1;
                }
            }
            else if (rightAppt == null)
            {
                return 1;
            }
            else
            {
                DateTime leftStart = leftAppt.StartDateTime;
                DateTime rightStart = rightAppt.StartDateTime;

                if (leftStart == rightStart)
                {
                    return 0;
                }
                else if (leftStart < rightStart)
                {
                    return -1;
                }
                else
                {
                    return 1;
                }
            }
        }

        #endregion Private Methods

        #region Public Methods

        /// <summary>
        /// Refreshes the list of appointments.
        /// </summary>
        /// <remarks>The CalendarService property must not be empty.</remarks>
        public void RefreshList()
        {
            if (CalendarService == null)
                throw new CalendarServiceIsNullException("The calendar service property has not been set.");

            Appointments = CalendarService.GetAllAppointments() as List<Appointment>;
        }        

        #endregion Public Methods
    }
}